home *** CD-ROM | disk | FTP | other *** search
- ;COMMA000.ASM テンキーの「000」を「,」に変換する
- page 58,132
- .8086
- comment *
- COMMA000.COM (C)1991. Boko.
-
- テンキー部の「000」キーを「,」(カンマ)に変更する。
-
- 常駐してINT 90(キーボードBIOS)をフックし、
- キーの読み取り時にコードをすりかえる
-
- 1991.05.19 V1.0 初版(Nifty-Serve FTOWNS1 DL3 にアップロード)
- 1991.06.09 常駐サイズの縮小
- 1991.08.11 V1.1 フリコレ4用(^^;)にコメントを追加
-
- *
-
- TAB EQU 009H ;タブコード
- CR EQU 00DH ;キャリッジリターンコード
- LF EQU 00AH ;ラインフィードコード
- EOS EQU '$' ;End Of String 文字列の終端(DOS call用)
-
- CODE SEGMENT ;COM形式
- ASSUME CS:CODE
- ASSUME DS:CODE
- ASSUME ES:CODE
-
- org 002CH
- ENV_SEG DW ? ;環境変数のセグメント(DOSが設定する)
-
- org 0070H
-
- ; データ部
- ; (PSP内のFCB領域をワークエリアとして利用している)
-
- KEY_INT_VEC label dword ;INT 90ベクトルの保存領域
- KEY_INT_OFF DW ?
- KEY_INT_SEG DW ?
-
- SAVE_AX DW ? ;キー待ちあり?なし?の保存領域
-
- org 0080h
- COMMAND_PARAM DB 80h dup(?) ;コマンドラインからのパラメータ
- ;(1文字目はパラメータの長さ)
-
- ; コード部
- ;
-
- org 0100h
- START:
- JMP short INITIALIZE ;初期化ルーチンへジャンプ
-
- ; 常駐部
- ; ~~~~~~
-
- ENTRY_INT90H proc far
- ;アプリケーションソフトが
- ;INT 90を実行するとまず
- ;ここに制御が移る
-
- ;INT 90 「文字の読込」のインタフェィス
- ;CALL WITH
- ; AH=09H
- ; AL=0 :キー入力待ち
- ; AL=1 :キー入力待ちなし
- ;RETURNS
- ; AH=0 :正常終了
- ; DH=0FFH :入力文字なし
- ; DH!=0FFH:入力文字あり
- ; DL: 文字コード/スキャンコード
- ; BH: キーアドレス
- ; BL: シフトキー状態
-
- CMP AH,009H ; 「文字の読込」の機能?
- JE ZERO_TO_COMMA
- JMP CS:KEY_INT_VEC ;それ以外は本当のINT 90hに制御を渡す
- ENTRY_INT90H endp
-
- ZERO_TO_COMMA proc far
- ;この部分が実行されるときには
- ;ES,DS,SSが何を指しているかは
- ;不定であることに注意。データ
- ;部をアクセスするためにCS:で
- ;セグメントオーバーライトする
- ;必要がある
-
- STI ;割り込み許可
- MOV CS:SAVE_AX,AX ;呼び出し機能をセーブしておく
-
- ;ここで本来のINT 90を呼ぶのだ
- ;が実際にINT 90Hを実行すると
- ;無限ループになるのでCALLで呼
- ;び出す。次のpushf~callで
- ;INT 90と同じになる。
-
- PUSHF
- CLI
- CALL CS:KEY_INT_VEC ;本当のINT 90h FUNC 9を呼ぶ
-
- ;「000」キー以外は呼び出しもとの
- ;アプリケーションに戻る
- ;キー待ちなしが指定されていて
- ;キー入力がないときも戻る
-
- CMP BH,04AH ;「000」キーのキーアドレス?
- JNE RETURN_TO_APL
-
- ;「000」キーの場合は一つ目と二つ目
- ;の「0」は読み捨てる
-
- MOV AX,CS:SAVE_AX
- PUSHF
- CLI
- CALL CS:KEY_INT_VEC ;本当のINT 90h FUNC 9をコール
- CMP BH,04AH ;「000」キーのキーアドレス?
- JNE RETURN_TO_APL
-
- ;「000」キーの場合三つ目の「0」を「,」
- ;に変えてもとのアプリに戻る
-
- MOV AX,CS:SAVE_AX
- PUSHF
- CLI
- CALL CS:KEY_INT_VEC ;本当のINT 90h FUNC 9をコール
- CMP BH,04AH ;「000」キーのキーアドレス?
- JNE RETURN_TO_APL
- MOV DL,',' ;CAMMAにすりかえる
- RETURN_TO_APL:
-
- ;呼び出しもとのアプリケーション
- ;にもどる。
- ;INTからの戻りなのでふつうの
- ;RET命令は使えないことに注意
-
- IRET
-
- ZERO_TO_COMMA endp
-
- ; 初期化部
- ; ~~~~~~~~
- ;初期化部はプログラムが起動
- ;したときに一度だけ実行される
- ;常駐終了するときに初期化部は
- ;開放される
-
-
- INITIALIZE proc
-
- ;コマンドラインのパラメータを
- ;チェックします。
-
- CLD
- MOV SI,offset COMMAND_PARAM+1
-
- SKIP_BLANK:
- LODSB
- CMP AL,' ' ;空白は無視
- JE SKIP_BLANK
- CMP AL,TAB ;タブコードは無視
- JE SKIP_BLANK
- CMP AL,CR ;パラメータは全く無かった
- JE NO_PARAM
-
- ;「S」とか「R」とかの直前の文字は
- ;「/」でも「-」でもよい
- ;はっきりいってなんでも良い
- ;(手抜き)
- ;またこれ以降の文字もまったく
- ;チェックしていない。したがって
- ;comma000 /s /r
- ;のように書くと最初のパラメータ
- ;のみが有効になる。
-
- LODSB
- CMP AL,'S'
- JE START_STAY ;S Stay 常駐開始
- CMP AL,'s'
- JE START_STAY
- CMP AL,'R' ;R Remove 常駐終了
- JE END_STAY
- CMP AL,'r'
- JE END_STAY
- NO_PARAM:
- ;パラメターなし
- CALL STAY_CHK
- JE END_STAY
- ; JMP START_STAY ;次に流れ込む
- INITIALIZE endp
-
-
- START_STAY PROC
-
- ; 常駐開始
-
- CALL STAY_CHK
- PUSH CS
- POP ES ;ES←CS
- JE ALREADY_STAY
-
- ;常駐しているかどうかの判断の
- ;鍵になる文字列を転送する
- ;PSP内を使うのはVMAPなどの
- ;メモリ利用状況表示ツールで
- ;PSPを見るものが多いから
-
- MOV DI,offset COMMAND_PARAM
- MOV SI,offset ID_MSG
- MOV CX,27
- REPNZ MOVSB
-
- ;INT 90のベクトルを取得する
-
- MOV AX,03590H ;割り込みベクトルの取得
- INT 021H ;DOSシステムコール
-
- ;INT 90のベルトルを保存する
- ;ES:BX 割込みベクトルのアドレス
-
- MOV KEY_INT_OFF,BX
- MOV KEY_INT_SEG,ES
-
- ;新しい割り込みベクトルの設定
- ;COMMA000の入口を設定する
-
- MOV DX,offset ENTRY_INT90H
- MOV AX,02590H ;割り込みベクトルの設定
- INT 021H ;DOSシステムコール
-
- ;常駐開始メッセージを出力
-
- ;MS-DOSのシステムコールで文字を
- ;出力する場合キーのチェックが
- ;行われる
- ;すでにINT 90は書換え済なので
- ;常駐部が呼ばれることになる
- ;もしもメッセージが正常に出力
- ;されない時は、常駐部が変なの
- ;かもしれません。
-
- MOV DX,offset STR_MSG
- CALL PUTS
-
- MOV ES,ENV_SEG ;環境変数エリアの
- MOV AH,049H ;メモリブロックの開放
- INT 021H ;DOSシステムコール
- XOR AX,AX ;AX←0
- MOV ENV_SEG,AX ;cf. ◎h!FM 1990-12-p148.
-
- ;常駐するメモリサイズの計算は
- ;パラグラフ単位なので計算が
- ;ちょっとめんどう
- ;PSPの分を忘れてはいけない
-
- MOV DX,(INITIALIZE+15-START)/10H+10H
- MOV AX,03100H ;常駐終了
- INT 021H ;DOSシステムコール
- START_STAY endp
-
- NO_OPERATION proc
-
- CANT_REMOVE: MOV DX,offset EN2_MSG
- JMP short PUT_END
- ALREADY_STAY:
- MOV DX,offset ST2_MSG
- PUT_END:
- CALL PUTS
- MOV AX,04C00H ;プロセスの終了(リタンコード0)
- INT 021H ;DOSシステムコール
- NO_OPERATION endp
-
-
- END_STAY proc
- CALL STAY_CHK
- JNE CANT_REMOVE
- ;INT90ベクタをもとに戻す
- LDS DX,ES:KEY_INT_VEC
- MOV AX,02590H ;割り込みベクタの設定
- INT 21H ;DOSシステムコール
- ;常駐していたメモリブロック開放
- MOV AH,049H ;メモリブロック(ES)の開放
- INT 21H ;DOSシステムコール
- ;常駐終了メッセージの出力
- PUSH CS
- POP DS
- MOV DX,offset END_MSG
- JMP PUT_END
- END_STAY endp
-
-
-
- STAY_CHK PROC
- ;すでにCOMMA000が常駐しているかどうかのチェック
- ;RETURN
- ; Z :COMMA000が常駐している
- ; NZ:COMMA000はみつからなかった
-
- ;「COMMA000」の文字列がINT 90のセグメントにあるかどうかを
- ;調べている。まぁこの程度のチェックで十分でしょう。
- ;本当は別のソフトがINT 90をフックしてるかもしれないのだが
- ;その場合は開放することもできなくなるのでチェックはしない。
-
- ;このルーチンからリターンした後はESの値が変わることに注意
-
- MOV AX,03590H ;割り込みベクトルの取得(ES:BX)
- INT 021H ;DOSシステムコール
-
- MOV DI,offset COMMAND_PARAM
- MOV SI,offset ID_MSG
- MOV CX,ID_LEN
- REPZ CMPSB
- RET
- STAY_CHK ENDP
-
- ; メッセージ出力
- ; (DX:メッセージ開始アドレス)
- ;MS-DOSのシステムコールによる
- ;文字列な出力なので
- ;Townsシステムソフトウェアで実行する場合は
- ;出力は見えない
-
- PUTS proc
- MOV AH,09H ;文字列の出力
- INT 021H ;DOSシステムコール
- RET
- PUTS endp
-
- ID_MSG DB 24
- DB 'Comma000 (C)1991. Boko.',CR,0
- STR_MSG DB 'Comma000 V1.1 for FM TOWNS & FMR Series'
- DB ' (C)1991. Boko.',CR,LF
- DB 'テンキーの「000」を「,」に変更します。',CR,LF
- DB EOS
- END_MSG DB 'テンキーの「000」はもとどおりの「000」です。',CR
- DB EOS
- ST2_MSG DB 'Comma000はすでに常駐しています',CR
- DB EOS
- EN2_MSG DB 'Comma000はありません',CR
- DB EOS
- ID_LEN = STR_MSG - ID_MSG
- CODE ENDS
- END START
-